package com.centaline.androidsalesblog.activities.mine;

import android.support.design.widget.TextInputLayout;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.widget.Button;
import android.widget.EditText;

import com.android.volley.VolleyError;
import com.centaline.androidsalesblog.R;
import com.centaline.androidsalesblog.activities.sale.RentDetailActivity;
import com.centaline.androidsalesblog.api.usercenter.RegisterApi;
import com.centaline.androidsalesblog.api.usercenter.UserInfoListApi;
import com.centaline.androidsalesblog.base.BaseActivity;
import com.centaline.androidsalesblog.constants.AppConstant;
import com.centaline.androidsalesblog.model.databaseobject.UserDo;
import com.centaline.androidsalesblog.model.responseobject.SmsRo;
import com.centaline.androidsalesblog.model.responseobject.UserInfoListRo;
import com.centaline.androidsalesblog.model.responseobject.UserRo;
import com.centaline.androidsalesblog.model.responseobject.VerificationCodeRo;
import com.centaline.androidsalesblog.rx.database.RxDataBase;
import com.centaline.androidsalesblog.rx.request.RxRequest;
import com.centaline.androidsalesblog.utils.TextFormatUtil;
import com.centanet.framework.interfaces.IResponseListener;
import com.centanet.framework.utils.PatternFormat;
import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.widget.RxTextView;
import com.trello.rxlifecycle.ActivityEvent;

import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.functions.Func3;
import rx.schedulers.Schedulers;

/**
 * 注册
 * <p/>
 * Created by fusl1 on 2015/12/23.
 * Modify by Lihq on 2016/01/12.
 */
public class RegisterActivity extends BaseActivity {

    private TextInputLayout til_phone;
    private TextInputLayout til_verification;
    private TextInputLayout til_password;
    private Button btn_verification_code;
    private Button btn_register;
    private EditText phoneEditText, verificationEditText, passwordEditText;

    @Override
    protected int setLayoutId() {
        return R.layout.activity_register;
    }

    @Override
    protected void findViews() {
        til_phone = (TextInputLayout) findViewById(R.id.til_phone);
        til_verification = (TextInputLayout) findViewById(R.id.til_verification);
        til_password = (TextInputLayout) findViewById(R.id.til_password);
        btn_verification_code = (Button) findViewById(R.id.btn_verification_code);
        btn_register = (Button) findViewById(R.id.btn_register);
    }

    @Override
    protected void initViews() {
        setUniversalToolbar(R.string.register);
        phoneEditText = til_phone.getEditText();
        verificationEditText = til_verification.getEditText();
        passwordEditText = til_password.getEditText();

        if (phoneEditText != null &&
                verificationEditText != null &&
                passwordEditText != null) {
            Observable<CharSequence> phoneChangeObservable = RxTextView.textChanges(phoneEditText).skip(1);
            Observable<CharSequence> verificationChangeObservable = RxTextView.textChanges(verificationEditText).skip(1);
            Observable<CharSequence> passwordChangeObservable = RxTextView.textChanges(passwordEditText).skip(1);

            phoneEditText.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

            phoneChangeObservable.
                    compose(this.<CharSequence>bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(new Action1<CharSequence>() {
                        @Override
                        public void call(CharSequence charSequence) {
                            Pattern pattern = Pattern.compile(PatternFormat.PhoneNumber);
                            Matcher matcher = pattern.matcher(charSequence);
                            boolean phoneValid = matcher.find();
                            btn_verification_code.setEnabled(phoneValid);
                            if (phoneValid) {
                                til_phone.setError(null);
                            } else if (til_phone.getError() == null) {
                                til_phone.setError(getString(R.string.error_phone));
                            }
                        }
                    });

            verificationChangeObservable.
                    compose(this.<CharSequence>bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(new Action1<CharSequence>() {
                        @Override
                        public void call(CharSequence charSequence) {
                            boolean verificationValid = charSequence.length() > 5;
                            if (verificationValid) {
                                til_verification.setError(null);
                            } else if (til_verification.getError() == null) {
                                til_verification.setError(getString(R.string.error_verification));
                            }
                        }
                    });

            passwordChangeObservable.
                    compose(this.<CharSequence>bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(new Action1<CharSequence>() {
                        @Override
                        public void call(CharSequence charSequence) {
                            boolean passwordValid = charSequence.length() > 5;
                            if (passwordValid) {
                                til_password.setError(null);
                            } else if (til_password.getError() == null) {
                                til_password.setError(getString(R.string.error_password));
                            }
                        }
                    });

            Observable.combineLatest(phoneChangeObservable, verificationChangeObservable, passwordChangeObservable,
                    new Func3<CharSequence, CharSequence, CharSequence, Boolean>() {
                        @Override
                        public Boolean call(CharSequence phoneNumber, CharSequence verificationCode, CharSequence passWord) {
                            Pattern pattern = Pattern.compile(PatternFormat.PhoneNumber);
                            Matcher matcher = pattern.matcher(phoneNumber);
                            boolean phoneValid = matcher.find();
                            boolean verificationValid = verificationCode.length() > 5;
                            boolean passwordValid = passWord.length() > 5;
                            return phoneValid && verificationValid && passwordValid;
                        }
                    })
                    .compose(this.<Boolean>bindUntilEvent(ActivityEvent.DESTROY))
                    .subscribe(new Action1<Boolean>() {
                        @Override
                        public void call(Boolean aBoolean) {
                            btn_register.setEnabled(aBoolean);
                        }
                    });
        }

        RxView.clicks(btn_verification_code)
                .throttleFirst(1, TimeUnit.SECONDS)
                .compose(this.<Void>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        checkPhone();
                    }
                });

        RxView.clicks(btn_register)
                .throttleFirst(1, TimeUnit.SECONDS)
                .compose(this.<Void>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Void>() {
                    @Override
                    public void call(Void aVoid) {
                        checkSmsCode();
                    }
                });
    }

    /**
     * 检查手机号是否注册
     */
    private void checkPhone() {
        UserInfoListApi userInfoListApi = new UserInfoListApi(RegisterActivity.class, UserInfoListRo.class,
                new IResponseListener<UserInfoListRo>() {
                    @Override
                    public void onResponse(UserInfoListRo userInfoListRo) {
                        if (userInfoListRo == null ||
                                userInfoListRo.getUserDos() == null ||
                                userInfoListRo.getUserDos().size() == 0) {//未注册手机号
                            smsCode();
                        } else {
                            toast("您输入的手机号码已被注册");
                        }
                    }

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        netWorkUnable();
                    }
                });
        userInfoListApi.setPhone(TextFormatUtil.formatPhoneNumber(phoneEditText));
        userInfoListApi.startRequest();
    }

    /**
     * 获取验证码
     */
    private void smsCode() {
        RxRequest.sms(LoginActivity.class, TextFormatUtil.formatPhoneNumber(phoneEditText))
                .compose(this.<SmsRo>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<SmsRo>() {
                    @Override
                    public void call(SmsRo smsRo) {
                        if (0 == smsRo.getResultNo()) {
                            verification();
                            toast("验证码将发送到您的手机上");
                        } else {
                            toast(smsRo.getMessage());
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        netWorkUnable();
                    }
                });
    }

    /**
     * 验证码倒计时
     */
    private void verification() {
        btn_verification_code.setClickable(false);
        Observable.interval(0, 1, TimeUnit.SECONDS).take(61)
                .compose(this.<Long>bindUntilEvent(ActivityEvent.DESTROY))
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long aLong) {
                        final long remain = 60 - aLong;
                        if (remain > 0) {
                            btn_verification_code.setText(String.format(Locale.CHINA, "%d秒后重新获取", 60 - aLong));
                        } else {
                            btn_verification_code.setClickable(true);
                            btn_verification_code.setText(getString(R.string.get_verification_code));
                        }
                    }
                });
    }

    /**
     * 检查验证码
     */
    private void checkSmsCode() {
        hideKeyboard(til_password);
        showLoadingDialog();
        hideKeyboard(btn_register);
        RxRequest.VerificationCode(LoginActivity.class,
                TextFormatUtil.formatPhoneNumber(phoneEditText),
                verificationEditText.getText().toString())
                .compose(this.<VerificationCodeRo>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<VerificationCodeRo>() {
                    @Override
                    public void call(VerificationCodeRo verificationCodeRo) {
                        if (verificationCodeRo.getResultNo() == 0) {
                            register();
                        } else {
                            cancelLoadingDialog();
                            snack(verificationCodeRo.getMessage());
                        }
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        cancelLoadingDialog();
                        netWorkUnable();
                    }
                });
    }

    /**
     * 注册
     */
    private void register() {
        RegisterApi registerApi = new RegisterApi(RentDetailActivity.class, UserRo.class, new IResponseListener<UserRo>() {

            @Override
            public void onResponse(UserRo userRo) {
                cancelLoadingDialog();
                UserDo userDo = userRo.getUserDo();
                if (userRo.getResultNo() != 0 ||
                        userDo == null) {
                    snack(userRo.getMessage());
                } else {
                    AppConstant.setUserLogin(RegisterActivity.this, userDo);
                    userSave(userDo);
                }
            }

            @Override
            public void onErrorResponse(VolleyError error) {
                cancelLoadingDialog();
                netWorkUnable();
            }
        });
        registerApi.setPhone(TextFormatUtil.formatPhoneNumber(phoneEditText));
        registerApi.setPassword(passwordEditText.getText().toString());
        registerApi.startRequest();
    }

    /**
     * 保存用户信息
     */
    private void userSave(UserDo userDo) {
        AppConstant.setUserLogin(this, userDo);
        RxDataBase.saveUser(userDo)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(this.<Boolean>bindUntilEvent(ActivityEvent.DESTROY))
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean aBoolean) {
                        snack("注册成功");
                        setResult(RESULT_OK);
                        finish();
                    }
                });
    }
}



